import pandas as pd

#1.异常范围为故障范围的两倍
#2.超过范围[mean-3*std,mean+3*std]也视为异常

class AbnormalHandle:
    def __init__(self,thresh,windowSize=30):
        self.windowSize = windowSize
        self.upper={}
        self.lower={}
        self.thresh=thresh
        self.errorRan={}
        for field in thresh:
            errorRan=thresh[field]["error"][1]-thresh[field]["error"][0]
            upper=thresh[field]["error"][1]+errorRan/2
            lower=thresh[field]["error"][0]-errorRan/2
            if lower<0:
                lower=0
            self.errorRan[field]=errorRan
            self.upper[field]=upper
            self.lower[field]=lower
        self.errorRan=pd.Series(self.errorRan)
        self.upper=pd.Series(self.upper)
        self.lower=pd.Series(self.lower)
        self.df=None

    def mergeDict(self,dic1,dic2):
        for key in dic2:
            if dic1.get(key) is None:
                dic1[key]=dic2[key]

    def add(self, dic):
        if self.df is None:
            #第一个数据默认不会发生异常
            self.df=pd.DataFrame(dic,index=[0])
            return dic,{},{}
        else:
            data=pd.Series(dic)
            data[data.isnull()]=-1#将缺失值设置为-1,后续显示会认为原值为-1的地方是数据缺失
            mean = self.df.mean()
            aboveDic={}
            belowDic={}
            if len(self.df)==self.windowSize:
                std = self.df.std()
                a=std-self.errorRan*0.1
                std[a[a<0].index]=10000#标准差过小时使用mean+-std无意义,将std设置为一个不可能的较高值
                tolerance=3*std
                lower=mean-tolerance
                upper=mean+tolerance
                above=data[data>upper]
                if above.shape[0]>0:
                    print(1)
                    data[data>upper]=mean
                    self.mergeDict(aboveDic,dict(above))
                below = data[data < lower]
                if below.shape[0] > 0:
                    print(2)
                    data[data < lower] = mean
                    self.mergeDict(belowDic,dict(below))
            diff=data-self.upper
            indice=diff[diff>0].index
            above=data[indice]
            if above.shape[0]>0:
                print(3)
                data[indice] = mean
                self.mergeDict(aboveDic, dict(above))
            diff=data-self.lower
            indice=diff[diff<0].index
            below = data[indice]
            if below.shape[0] > 0:
                print(4)
                data[indice] = mean
                self.mergeDict(belowDic, dict(below))
            self.df=self.df.append(data,ignore_index=True)
            if len(self.df)>self.windowSize:
                self.df.drop([self.df.index[0]],inplace=True)
            return dict(data),belowDic,aboveDic

